package com.maodou.core.ui.components.textfield

import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
import java.text.DecimalFormat
import java.util.regex.Pattern

/**
 * 输入框工具类
 * 提供各种输入过滤器、格式化器和验证工具
 */
object TextFieldUtils {
    
    /**
     * 输入过滤器
     */
    object Filters {
        
        /**
         * 只允许数字输入
         */
        fun numbersOnly(input: String): String {
            return input.filter { it.isDigit() }
        }
        
        /**
         * 只允许字母输入
         */
        fun lettersOnly(input: String): String {
            return input.filter { it.isLetter() }
        }
        
        /**
         * 只允许字母和数字输入
         */
        fun alphanumericOnly(input: String): String {
            return input.filter { it.isLetterOrDigit() }
        }
        
        /**
         * 只允许字母、数字和下划线
         */
        fun usernameChars(input: String): String {
            return input.filter { it.isLetterOrDigit() || it == '_' }
        }
        
        /**
         * 小数输入过滤器
         * @param decimalPlaces 小数位数，-1表示不限制
         */
        fun decimal(input: String, decimalPlaces: Int = -1): String {
            val regex = if (decimalPlaces > 0) {
                "^\\d*\\.?\\d{0,$decimalPlaces}$"
            } else {
                "^\\d*\\.?\\d*$"
            }
            
            return if (input.matches(Regex(regex))) {
                input
            } else {
                // 如果不匹配，尝试修复
                val parts = input.split(".")
                when {
                    parts.size == 1 -> parts[0].filter { it.isDigit() }
                    parts.size == 2 -> {
                        val integerPart = parts[0].filter { it.isDigit() }
                        val decimalPart = parts[1].filter { it.isDigit() }
                        val limitedDecimalPart = if (decimalPlaces > 0) {
                            decimalPart.take(decimalPlaces)
                        } else {
                            decimalPart
                        }
                        "$integerPart.$limitedDecimalPart"
                    }
                    else -> parts[0].filter { it.isDigit() }
                }
            }
        }
        
        /**
         * 手机号输入过滤器
         */
        fun phoneNumber(input: String): String {
            return input.filter { it.isDigit() }.take(11)
        }
        
        /**
         * 身份证号输入过滤器
         */
        fun idCard(input: String): String {
            return input.filter { it.isDigit() || it.uppercase() == "X" }.take(18)
        }
        
        /**
         * 银行卡号输入过滤器
         */
        fun bankCard(input: String): String {
            return input.filter { it.isDigit() || it == ' ' }
        }
        
        /**
         * 邮箱输入过滤器（基础过滤）
         */
        fun email(input: String): String {
            return input.filter { it.isLetterOrDigit() || it in "@.-_+" }
        }
        
        /**
         * 价格输入过滤器（最多2位小数）
         */
        fun price(input: String): String {
            return decimal(input, 2)
        }
        
        /**
         * 自定义字符集过滤器
         */
        fun customChars(allowedChars: String): (String) -> String {
            return { input -> input.filter { it in allowedChars } }
        }
    }
    
    /**
     * 格式化器
     */
    object Formatters {
        
        /**
         * 手机号格式化（138 0013 8000）
         */
        fun formatPhoneNumber(input: String): String {
            val digits = input.filter { it.isDigit() }
            return when {
                digits.length <= 3 -> digits
                digits.length <= 7 -> "${digits.substring(0, 3)} ${digits.substring(3)}"
                else -> "${digits.substring(0, 3)} ${digits.substring(3, 7)} ${digits.substring(7)}"
            }
        }
        
        /**
         * 银行卡号格式化（每4位一组）
         */
        fun formatBankCard(input: String): String {
            val digits = input.filter { it.isDigit() }
            return digits.chunked(4).joinToString(" ")
        }
        
        /**
         * 身份证号格式化（前6位 中8位 后4位）
         */
        fun formatIdCard(input: String): String {
            val cleaned = input.filter { it.isDigit() || it.uppercase() == "X" }
            return when {
                cleaned.length <= 6 -> cleaned
                cleaned.length <= 14 -> "${cleaned.substring(0, 6)} ${cleaned.substring(6)}"
                else -> "${cleaned.substring(0, 6)} ${cleaned.substring(6, 14)} ${cleaned.substring(14)}"
            }
        }
        
        /**
         * 价格格式化（添加千分位分隔符）
         */
        fun formatPrice(input: String): String {
            if (input.isEmpty()) return input
            
            return try {
                val number = input.toDouble()
                val formatter = DecimalFormat("#,##0.00")
                formatter.format(number)
            } catch (e: NumberFormatException) {
                input
            }
        }
        
        /**
         * 数字格式化（添加千分位分隔符）
         */
        fun formatNumber(input: String): String {
            if (input.isEmpty()) return input
            
            return try {
                val number = input.toLong()
                val formatter = DecimalFormat("#,###")
                formatter.format(number)
            } catch (e: NumberFormatException) {
                input
            }
        }
    }
    
    /**
     * 验证器
     */
    object Validators {
        
        /**
         * 邮箱验证
         */
        fun isValidEmail(email: String): Boolean {
            val emailPattern = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
            return Pattern.matches(emailPattern, email)
        }
        
        /**
         * 手机号验证（中国大陆）
         */
        fun isValidPhoneNumber(phone: String): Boolean {
            val phonePattern = "^1[3-9]\\d{9}$"
            return Pattern.matches(phonePattern, phone.filter { it.isDigit() })
        }
        
        /**
         * 身份证号验证
         */
        fun isValidIdCard(idCard: String): Boolean {
            val cleaned = idCard.filter { it.isDigit() || it.uppercase() == "X" }
            if (cleaned.length != 18) return false
            
            // 简单的身份证号格式验证
            val idCardPattern = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$"
            return Pattern.matches(idCardPattern, cleaned)
        }
        
        /**
         * 银行卡号验证（Luhn算法）
         */
        fun isValidBankCard(cardNumber: String): Boolean {
            val digits = cardNumber.filter { it.isDigit() }
            if (digits.length < 16 || digits.length > 19) return false
            
            return luhnCheck(digits)
        }
        
        /**
         * URL验证
         */
        fun isValidUrl(url: String): Boolean {
            val urlPattern = "^(https?|ftp)://[^\\s/$.?#].[^\\s]*$"
            return Pattern.matches(urlPattern, url)
        }
        
        /**
         * 密码强度验证
         */
        fun getPasswordStrength(password: String): PasswordStrength {
            var score = 0
            val checks = mutableListOf<String>()
            
            // 长度检查
            when {
                password.length >= 12 -> {
                    score += 2
                    checks.add("长度充足")
                }
                password.length >= 8 -> {
                    score += 1
                    checks.add("长度适中")
                }
                else -> checks.add("长度过短")
            }
            
            // 字符类型检查
            if (password.any { it.isLowerCase() }) {
                score += 1
                checks.add("包含小写字母")
            }
            
            if (password.any { it.isUpperCase() }) {
                score += 1
                checks.add("包含大写字母")
            }
            
            if (password.any { it.isDigit() }) {
                score += 1
                checks.add("包含数字")
            }
            
            if (password.any { !it.isLetterOrDigit() }) {
                score += 1
                checks.add("包含特殊字符")
            }
            
            return when {
                score >= 5 -> PasswordStrength.STRONG
                score >= 3 -> PasswordStrength.MEDIUM
                score >= 1 -> PasswordStrength.WEAK
                else -> PasswordStrength.VERY_WEAK
            }
        }
        
        /**
         * Luhn算法验证银行卡号
         */
        private fun luhnCheck(cardNumber: String): Boolean {
            var sum = 0
            var alternate = false
            
            for (i in cardNumber.length - 1 downTo 0) {
                var n = cardNumber[i].toString().toInt()
                
                if (alternate) {
                    n *= 2
                    if (n > 9) {
                        n = (n % 10) + 1
                    }
                }
                
                sum += n
                alternate = !alternate
            }
            
            return sum % 10 == 0
        }
    }
    
    /**
     * 密码强度枚举
     */
    enum class PasswordStrength(val label: String, val color: androidx.compose.ui.graphics.Color) {
        VERY_WEAK("很弱", androidx.compose.ui.graphics.Color.Red),
        WEAK("弱", androidx.compose.ui.graphics.Color(0xFFFF9800)),
        MEDIUM("中等", androidx.compose.ui.graphics.Color(0xFFFFEB3B)),
        STRONG("强", androidx.compose.ui.graphics.Color.Green)
    }
}

/**
 * 手机号格式化视觉变换
 */
class PhoneNumberVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        val formatted = TextFieldUtils.Formatters.formatPhoneNumber(text.text)
        
        val offsetMapping = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                val digits = text.text.take(offset).filter { it.isDigit() }
                return when {
                    digits.length <= 3 -> digits.length
                    digits.length <= 7 -> digits.length + 1
                    else -> digits.length + 2
                }
            }
            
            override fun transformedToOriginal(offset: Int): Int {
                return when {
                    offset <= 3 -> offset
                    offset <= 8 -> offset - 1
                    else -> offset - 2
                }.coerceAtMost(text.text.length)
            }
        }
        
        return TransformedText(AnnotatedString(formatted), offsetMapping)
    }
}

/**
 * 身份证号格式化视觉变换
 */
class IdCardVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        val formatted = TextFieldUtils.Formatters.formatIdCard(text.text)
        
        val offsetMapping = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                val chars = text.text.take(offset)
                return when {
                    chars.length <= 6 -> chars.length
                    chars.length <= 14 -> chars.length + 1
                    else -> chars.length + 2
                }
            }
            
            override fun transformedToOriginal(offset: Int): Int {
                return when {
                    offset <= 6 -> offset
                    offset <= 15 -> offset - 1
                    else -> offset - 2
                }.coerceAtMost(text.text.length)
            }
        }
        
        return TransformedText(AnnotatedString(formatted), offsetMapping)
    }
}

/**
 * 价格格式化视觉变换
 */
class PriceVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        if (text.text.isEmpty()) {
            return TransformedText(text, OffsetMapping.Identity)
        }
        
        val formatted = "¥${TextFieldUtils.Formatters.formatPrice(text.text)}"
        
        val offsetMapping = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                return offset + 1 // 加上¥符号
            }
            
            override fun transformedToOriginal(offset: Int): Int {
                return (offset - 1).coerceAtLeast(0)
            }
        }
        
        return TransformedText(AnnotatedString(formatted), offsetMapping)
    }
}

/**
 * 数字格式化视觉变换（千分位分隔符）
 */
class NumberVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        if (text.text.isEmpty()) {
            return TransformedText(text, OffsetMapping.Identity)
        }
        
        val formatted = TextFieldUtils.Formatters.formatNumber(text.text)
        
        val offsetMapping = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                val originalText = text.text.take(offset)
                val commaCount = (originalText.length - 1) / 3
                return offset + commaCount
            }
            
            override fun transformedToOriginal(offset: Int): Int {
                val commaCount = formatted.take(offset).count { it == ',' }
                return (offset - commaCount).coerceAtLeast(0)
            }
        }
        
        return TransformedText(AnnotatedString(formatted), offsetMapping)
    }
}